using System;
using System.Collections.Generic;
//using System.Numerics;
using System.Threading.Tasks;

namespace snacks
{
    abstract class Controller {
        public abstract Vector GetDirection();
        //public Vector<int> Direction;
    }

    class ConsoleController : Controller
    {
        Vector cur = new Vector(-1, 0);
        Snake s;

        public override Vector GetDirection()
        {
            if(Console.KeyAvailable) {
                ConsoleKey k = new ConsoleKey();
                Vector tmp;
                while(Console.KeyAvailable) k = Console.ReadKey(true).Key;
                switch(k) {
                    case ConsoleKey.LeftArrow:
                        tmp = new Vector(-1, 0);
                        break;
                    case ConsoleKey.RightArrow:
                        tmp = new Vector(1, 0);
                        break;
                    case ConsoleKey.UpArrow:
                        tmp = new Vector(0, -1);
                        break;
                    case ConsoleKey.DownArrow:
                        tmp = new Vector(0, 1);
                        break;
                    default:
                        tmp = new Vector(-1, 0);
                        break;
                }
                if (-tmp != s.HeadDir) cur = tmp;
            }

            return cur;
        }

        public ConsoleController(Snake s)
        {
            this.s = s;
        }
    }

    class AIController : Controller {
        Snake snake;
        GameManager gameManager;
        Map map;

        public AIController(GameManager gm, Map m, Snake s){
            gameManager = gm;
            map = m;
            snake = s;
        }

        Vector GetFourDir(int i)
        {
            Vector tmp;
            switch(i)
            {
                case 0:
                    tmp = new Vector(-1, 0);
                    break;
                case 1:
                    tmp = new Vector(1, 0);
                    break;
                case 2:
                    tmp = new Vector(0, -1);
                    break;
                default:
                    tmp = new Vector(0, 1);
                    break;
            }
            return tmp;
        }

        public override Vector GetDirection()
        {
            // Vector tmp;

            // for (int i = 0; i < 4; ++i)
            // {
            //     tmp = GetFourDir(i);
            //     if (map[snake.HeadPos + tmp].Type == BType.Snack) return tmp;
            // }

            // bool[] used = new bool[4];
            // int rnd;

            // while (!(used[0] && used[1] && used[2] && used[3]))
            // {
            //     rnd = gameManager.Random.Next(0, 4);
            //     used[rnd] = true;
            //     tmp = GetFourDir(rnd);
            //     if (-tmp != snake.HeadDir && map[snake.HeadPos + tmp].Type == BType.None) return tmp;
            // }

            // return snake.HeadDir;

            Vector t = snake.HeadDir + snake.HeadPos;
            int mif = 0, mi = 0x3fffffff, di = -1;
            if(map[t].Type == BType.Snake || map[t].Type == BType.Wall) ++mi;   //must chang your way
            int[] lis = GetRndArr();
            foreach(int i in lis){
                t = snake.HeadPos + GetFourDir(i);
                if(map[t].Type == BType.Snake || map[t].Type == BType.Wall) continue;
                else if(mif < map.ConSize[t.x, t.y] ||(
                mif == map.ConSize[t.x, t.y] && mi > map.SnackDis[t.x, t.y])){
                    mi = map.SnackDis[t.x, t.y];
                    mif = map.ConSize[t.x, t.y];
                    di = i;
                }
            }

            // if (di != -1 && map[GetFourDir(di) + snake.HeadPos].Type == BType.Wall && map[GetFourDir(di) + snake.HeadPos].Type == BType.Snake){
            //     Console.WriteLine("hora!!");
            // }

            // if (di == -1){
            //     ++cmin;
            //     // Console.WriteLine("hora!!");
            //     // Console.WriteLine("shineyo!!");
            // } else cmin = 0;
            // if(cmin > 2){
            //     Console.Write("kora!");
            //     Console.Write("mituketayo");
            // }

            return di == -1 ? snake.HeadDir : GetFourDir(di);
        }
        // int cmin = 0;

        int[] GetRndArr(){
            // return new int[]{0, 1, 2, 3};
            List<int> l = new List<int>();
            
            bool[] u = new bool[4];
            int i;
            while(!(u[0] && u[1] && u[2] && u[3])) {
                i = gameManager.Random.Next(0, 4);
                if(u[i])    continue;
                u[i] = true;
                l.Add(i);
            }
            
            return l.ToArray();
        }
    }
}

/*
 * 1. AI
 */